package utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import lombok.Data;
import lombok.SneakyThrows;
import main.Main;
import messagetype.*;
import view.AddNewFriend;
import view.MainWindow;
import view.NewFriend;
import view.controller.MainWindowController;

import java.io.*;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author
 */

@Data
public class receiveRunnable implements Runnable {
    private Socket s;
    DataInputStream dis = null;
    DataOutputStream dos = null;
    public static Boolean flag = false;


    @Override
    public void run() {
        try {
            readServerMsg();
        } catch (Exception e) {

        }
    }

    public void readServerMsg() throws IOException, InterruptedException {
        while (true) {
            MsHead msg = MsgTool.readMsgHead(dis);
            byte type = msg.getType();
            if (type==0x03) {
                ChatMsg cm = (ChatMsg) msg;
                UserMsgToUser um = JSON.parseObject(cm.getPrivateMsg(), UserMsgToUser.class);
                receiveMessageFromUser(um.getSrcUser(), um.getMessage());
            } else if (type == 0x07) {
                FindMsg fm1 = (FindMsg) msg;
                int flag = fm1.getFlag();
                System.out.println(flag);
                User user = JSON.parseObject(fm1.getInformation(), User.class);
                if (flag == 1) {
                    addUser(user);
                } else if (flag == 0) {
                    showUserInformation(user);
                }
            } else if (type == 0x08) {
                FindImageMsg fIm = (FindImageMsg) msg;
                AccountAndImage aai = JSON.parseObject(fIm.getAccountAndImage(), AccountAndImage.class);
                if (aai.getImage() != null) {
                    byte[] b = ImgUtil.decode(aai.getImage());
                    File file = new File(String.format("photo/%s.png", aai.getAccount()));
                    FileOutputStream fos = new FileOutputStream(file);
                    fos.write(b);
                    fos.flush();
                    fos.close();
                    file.createNewFile();
                }
                loadImage(aai.getAccount());
            } else if (type == 0x10) {
                FindResList frl1 = (FindResList) msg;
                List<User> list = JSONArray.parseArray(frl1.getUserInformation(), User.class);
                showNewFriendList(list);
            } else if (type == 0x11) {
                AddFriendResMsg afrm = (AddFriendResMsg) msg;
                User srcUser = JSON.parseObject(afrm.getInformation(), User.class);
                addUser(srcUser);
            } else if (type == 0x12) {
                FriendMsgList fml = (FriendMsgList) msg;
                List<Message> msgList = JSON.parseArray(fml.getMsgList(), Message.class);
                loadFriendMessage(msgList);
            } else if (type == 0x13) {
                DeleteFriendMsg dfm = (DeleteFriendMsg) msg;
                UserToUser userToUser = JSON.parseObject(dfm.getInformation(), UserToUser.class);
                deleteFriend(userToUser.getSrcUser());
            } else if (type == 0x14) {
                CreateGroupMsg cg = (CreateGroupMsg) msg;
                Group group = JSON.parseObject(cg.getGroupInformation(), Group.class);
                createGroup(group);
            } else if (type == 0x16) {
                AddUserToGroupResMsg aut = (AddUserToGroupResMsg) msg;
                UserGroupToUser ug = JSON.parseObject(aut.getInformation(), UserGroupToUser.class);
                addGroupToList(ug.getGroup());
            } else if (type == 0x17) {
                TogetherChatMsg tt = (TogetherChatMsg) msg;
                UserMsgToGroup um = JSON.parseObject(tt.getInformation(), UserMsgToGroup.class);
                receiveMessageFromGroup(um.getUser(), new Group(um.getGroupAccount(), null), um.getMessage());
            } else if (type == 0x18) {
                GroupMsgList gm = (GroupMsgList) msg;
                List<Message> groupMsgList = JSON.parseArray(gm.getInformation(), Message.class);
                loadGroupMessage(groupMsgList);
            } else if (type == 0x20) {
                UpdateListMsg ulm = (UpdateListMsg) msg;
                UpdateList ul = JSON.parseObject(ulm.getInformation(), UpdateList.class);
                Group group = ul.getGroup();
                updateGroup(ul.getUser(), group, ulm.getState());
            }
        }
    }

    private void loadImage(String account) {
       if(account.equals(MainWindow.getMainWindow().getUser().getAccount())){
           ImageView iv = new ImageView("file:photo/" + MainWindow.getMainWindow().getUser().getAccount() + ".png");
           iv.setFitHeight(50);
           iv.setFitWidth(50);
           MainWindow.getMainWindow().getHeadTab().setGraphic(iv);
           MainWindow.getMainWindow().getHeadTab().setStyle("-fx-background-color: rgb(51,51,51)");
           MainWindow.getMainWindow().getHeadTab().setText("  ");
       }else{
           User user=MainWindow.getMainWindow().getUser();
           for (Group group : user.getGroups()) {
               if(account.equals(group.getGroupAccount())){
                   MainWindow.getMainWindow().addGroupToGroupList(group);
               }
           }
       }
    }

    private void createGroup(Group group) {
        System.out.println("创建的群聊账号为:" + group.getGroupAccount());
        MainWindow.getMainWindow().getUser().getGroups().add(group);
        try {
            byte[] b = ImgUtil.decode(group.getImage());
            FileOutputStream fos = new FileOutputStream("photo/" + group.getGroupAccount() + ".png");
            fos.write(b);
        } catch (Exception e) {
            System.out.println("设置群头像失败");
        }
        System.out.println(group);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                MainWindowController.groupMessagePageList.add(FXCollections.observableArrayList());

                MainWindowController.groups.add(group);

                MainWindow.getMainWindow().addGroupToGroupList(group);
            }
        });
    }

    private void showUserInformation(User user) throws InterruptedException {
        if (user == null || user.getAccount() == null) {

            Platform.runLater(new Runnable() {
                @Override
                public void run() {

                    AddNewFriend.getAddNewFriend().getBackPane().setVisible(false);
                    Alert alert = new Alert(Alert.AlertType.INFORMATION, "该用户不存在", new ButtonType("确认", ButtonBar.ButtonData.YES));
                    System.out.println(alert);
                    alert.setTitle("提示");
                    System.out.println(user);
                    alert.show();
                }
            });


        } else {
            AddNewFriend.getAddNewFriend().setChooseUser(user);
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    AddNewFriend.getAddNewFriend().getBackPane().setVisible(true);
                    Image p = new Image(String.format("file:photo/%s.png", user.getAccount()));

                    AddNewFriend.getAddNewFriend().getHeadImage().setImage(p);//头像
                    AddNewFriend.getAddNewFriend().getUserLabel().setText(user.getName());
                }
            });

        }
    }

    private void addUser(User user) {

        MainWindowController.friendMessagePageList.add(FXCollections.observableArrayList());

        MainWindow.getMainWindow().getFriends().add(user);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                MainWindow.getMainWindow().addFriendToFriendList(user);

                MainWindow.getMainWindow().addFriendToChatList(user);
            }
        });

    }

    public receiveRunnable(Socket s) throws IOException {
        this.s = s;
        dis = Connect.getConnect().dis;
        dos = Connect.getConnect().dos;
    }

    private void showNewFriendList(List<User> list) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                if (list == null || list.size() == 0) {//没有新的请求
                    Alert alert = new Alert(Alert.AlertType.INFORMATION, "暂无新的好友请求", new ButtonType("确认", ButtonBar.ButtonData.YES));
                    alert.setTitle("提示");
                    alert.show();
                } else {
                    //加载新好友请求
                    try {
                        NewFriend.getNewFriend().startWindow();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                for (User x : list) {
                    HBox h = new HBox();
                    String str = String.format("file:photo/%s.png", x.getAccount());
                    ImageView g = new ImageView(str);
                    g.setFitHeight(50);
                    g.setFitWidth(50);

                    VBox v = new VBox();
                    Label l = new Label(x.getName());
                    l.setPrefHeight(25);
                    Label label = new Label("最新消息");
                    label.setPrefHeight(25);
                    v.getChildren().addAll(l, label);

                    Button b1 = new Button("添加");
                    Button b2 = new Button("拒绝");
                    b1.setOnAction(new EventHandler<ActionEvent>() {
                        @SneakyThrows
                        @Override
                        public void handle(ActionEvent event) {
                            Connect connect = Connect.getConnect();
                            connect.handFriendRequests(MainWindow.getMainWindow().getUser(), x, (byte) 1);

                            int num = list.indexOf(x);

                            x.getAccount();
                            //User friend=Connect.getConnect().getUserByAccount(x.getAccount());
                            User friend = x;

                            MainWindowController.friends.add(friend);

                            MainWindowController.friendMessagePageList.add(FXCollections.observableArrayList());

                            MainWindow.getMainWindow().addFriendToChatList(friend);
                            MainWindow.getMainWindow().addFriendToFriendList(friend);

                            list.remove(num);
                            NewFriend.getNewFriend().getNewFriendList1().remove(num);
                        }
                    });
                    b2.setOnAction(new EventHandler<ActionEvent>() {
                        @SneakyThrows
                        @Override
                        public void handle(ActionEvent event) {
                            Connect connect = Connect.getConnect();
                            connect.handFriendRequests(MainWindow.getMainWindow().getUser(), x, (byte) 2);
                            int num = list.indexOf(x);
                            list.remove(num);
                            NewFriend.getNewFriend().getNewFriendList1().remove(num);

                        }
                    });


                    h.getChildren().addAll(g, v, b1, b2);
                    NewFriend.getNewFriend().getNewFriendList1().add(h);
                }
            }
        });
    }

    public void receiveMessageFromUser(User srcUser, String message) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                int num = MainWindowController.friends.indexOf(srcUser);
                MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
                MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setOnLeft(message, srcUser.getAccount()));
                if (num > 0) {
                    MainWindowController.friendList1.add(4, MainWindowController.friendList1.remove(num + 4));
                    MainWindowController.chatList1.add(0, MainWindowController.chatList1.remove(num));
                    MainWindowController.friends.add(0, MainWindowController.friends.remove(num));
                    MainWindowController.friendMessagePageList.add(0, MainWindowController.friendMessagePageList.remove(num));
                }

            }
        });
    }

    public void receiveMessageFromGroup(User srcUser, Group desGroup, String message) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                int num = MainWindowController.groups.indexOf(desGroup);
                MainWindowController.groupMessagePageList.get(num).add(new MessageBubble().setTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
                MainWindowController.groupMessagePageList.get(num).add(new MessageBubble().setOnLeft(message, srcUser.getAccount()));
                if (num > 0) {
                    MainWindowController.groupList1.add(0, MainWindowController.groupList1.remove(num));
                    MainWindowController.groups.add(0, MainWindowController.groups.remove(num));
                    MainWindowController.groupMessagePageList.add(0, MainWindowController.groupMessagePageList.remove(num));
                }

            }
        });
    }

    public void loadFriendMessage(List<Message> list) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                for (Message message : list) {
                    int num = 0;
                    if (message.getSender().equals(MainWindow.getMainWindow().getUser().getAccount())) {
                        User sender = new User(message.getSender());
                        User receiver = new User(message.getReceiver());
                        num = MainWindowController.friends.indexOf(receiver);
                        MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setTime(message.getDate()));
                        MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setOnRight(message.getMessage(), sender.getAccount()));

                    } else if (message.getReceiver().equals(MainWindow.getMainWindow().getUser().getAccount())) {
                        User sender = new User(message.getSender());
                        User receiver = new User(message.getReceiver());
                        num = MainWindowController.friends.indexOf(sender);
                        MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setTime(message.getDate()));
                        MainWindowController.friendMessagePageList.get(num).add(new MessageBubble().setOnLeft(message.getMessage(), sender.getAccount()));
                    }
                    if (num > 0) {
                        MainWindowController.friendList1.add(4, MainWindowController.friendList1.remove(num + 4));
                        MainWindowController.chatList1.add(0, MainWindowController.chatList1.remove(num));
                        MainWindowController.friends.add(0, MainWindowController.friends.remove(num));
                        MainWindowController.friendMessagePageList.add(0, MainWindowController.friendMessagePageList.remove(num));
                    }
                }

            }
        });

    }

    public void loadGroupMessage(List<Message> list) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                Collections.sort(list, new Comparator<Message>() {
                    @Override
                    public int compare(Message o1, Message o2) {
                        return o1.getDate().compareTo(o2.getDate());
                    }
                });
                for (Message message : list) {
                    User sender = new User(message.getSender());
                    Group receiver = new Group(message.getReceiver(), null);

                    int index = MainWindowController.groups.indexOf(receiver);
                    MainWindowController.groupMessagePageList.get(index).add(new MessageBubble().setTime(message.getDate()));

                    if (message.getSender().equals(MainWindow.getMainWindow().getUser().getAccount())) {
                        MainWindowController.groupMessagePageList.get(index).add(new MessageBubble().setOnRight(message.getMessage(), sender.getAccount()));
                    } else {

                        MainWindowController.groupMessagePageList.get(index).add(new MessageBubble().setOnLeft(message.getMessage(), sender.getAccount()));
                    }
                    if (index > 0) {
                        MainWindowController.groupList1.add(0, MainWindowController.groupList1.remove(index));
                        MainWindowController.groups.add(0, MainWindowController.groups.remove(index));
                        MainWindowController.groupMessagePageList.add(0, MainWindowController.groupMessagePageList.remove(index));
                    }
                }

            }
        });
    }

    public void deleteFriend(User srcUser) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                int index = MainWindowController.friends.indexOf(srcUser);
                MainWindowController.chatList1.remove(index);
                MainWindowController.friendList1.remove(index + 4);
                MainWindowController.friends.remove(index);
                MainWindowController.friendMessagePageList.remove(index);
                if(MainWindowController.friendMessagePageList.size()==0){
                    MainWindowController.chooseFriendMessagePage.clear();
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            MainWindow.getMainWindow().getFriendName().setText(" ");
                        }
                    });
                }
            }
        });
    }

    public void updateGroup(User user, Group group, int flag) {
        int index = MainWindowController.groups.indexOf(group);
        int dissolutionGroup=2;
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if (flag == 1) {
                    MainWindowController.groups.get(index).getMembers().add(user);
                } else if (flag == 0) {
                    MainWindowController.groups.get(index).getMembers().remove(user);
                }else  if(flag==dissolutionGroup){
                    MainWindowController.groups.remove(index);
                    MainWindowController.groupMessagePageList.remove(index);
                    MainWindowController.groupList1.remove(index);
                    if(MainWindowController.groupMessagePageList.size()==0){
                        MainWindowController.chooseGroupMessagePage.clear();
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                MainWindow.getMainWindow().getGroupName().setText("  ");
                            }
                        });
                    }
                }
            }
        });
    }

    public void addGroupToList(Group group) {
        System.out.println("有人拉我进群");
        File file = new File("photo/" + group.getGroupAccount() + ".png");
        if (!file.exists()) {
            byte[] b = ImgUtil.decode(group.getImage());
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream("photo/" + group.getGroupAccount() + ".png");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fos != null) {
                        fos.write(b);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                MainWindowController.groupMessagePageList.add(FXCollections.observableArrayList());
                MainWindowController.groups.add(group);
                MainWindow.getMainWindow().addGroupToGroupList(group);
            }
        });
    }


}
